home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / vid_dll.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-11-09  |  14.6 KB  |  649 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // Main windowed and fullscreen graphics interface module. This module
  21. // is used for both the software and OpenGL rendering versions of the
  22. // Quake refresh engine.
  23. #include <assert.h>
  24. #include <float.h>
  25.  
  26. #include "..\client\client.h"
  27. #include "winquake.h"
  28. //#include "zmouse.h"
  29.  
  30. cvar_t *win_noalttab;
  31.  
  32. #ifndef WM_MOUSEWHEEL
  33. #define WM_MOUSEWHEEL (WM_MOUSELAST+1)  // message that will be supported by the OS 
  34. #endif
  35.  
  36. static UINT MSH_MOUSEWHEEL;
  37.  
  38. // Console variables that we need to access from this module
  39. cvar_t        *vid_gamma;
  40. cvar_t        *vid_ref;            // Name of Refresh DLL loaded
  41. cvar_t        *vid_xpos;            // X coordinate of window position
  42. cvar_t        *vid_ypos;            // Y coordinate of window position
  43. cvar_t        *vid_fullscreen;
  44.  
  45. // Global variables used internally by this module
  46. viddef_t    viddef;                // global video state; used by other modules
  47. qboolean    reflib_active = 0;
  48.  
  49. HWND        cl_hwnd;            // Main window handle for life of program
  50.  
  51. #define VID_NUM_MODES ( sizeof( vid_modes ) / sizeof( vid_modes[0] ) )
  52.  
  53. LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  54.  
  55. static qboolean s_alttab_disabled;
  56.  
  57. extern    unsigned    sys_msg_time;
  58.  
  59. /*
  60. ** WIN32 helper functions
  61. */
  62. extern qboolean s_win95;
  63.  
  64. static void WIN_DisableAltTab( void )
  65. {
  66.     if ( s_alttab_disabled )
  67.         return;
  68.  
  69.     if ( s_win95 )
  70.     {
  71.         BOOL old;
  72.  
  73.         SystemParametersInfo( SPI_SCREENSAVERRUNNING, 1, &old, 0 );
  74.     }
  75.     else
  76.     {
  77.         RegisterHotKey( 0, 0, MOD_ALT, VK_TAB );
  78.         RegisterHotKey( 0, 1, MOD_ALT, VK_RETURN );
  79.     }
  80.     s_alttab_disabled = true;
  81. }
  82.  
  83. static void WIN_EnableAltTab( void )
  84. {
  85.     if ( s_alttab_disabled )
  86.     {
  87.         if ( s_win95 )
  88.         {
  89.             BOOL old;
  90.  
  91.             SystemParametersInfo( SPI_SCREENSAVERRUNNING, 0, &old, 0 );
  92.         }
  93.         else
  94.         {
  95.             UnregisterHotKey( 0, 0 );
  96.             UnregisterHotKey( 0, 1 );
  97.         }
  98.  
  99.         s_alttab_disabled = false;
  100.     }
  101. }
  102.  
  103. //==========================================================================
  104.  
  105. byte        scantokey[128] = 
  106.                     { 
  107. //  0           1       2       3       4       5       6       7 
  108. //  8           9       A       B       C       D       E       F 
  109.     0  ,    27,     '1',    '2',    '3',    '4',    '5',    '6', 
  110.     '7',    '8',    '9',    '0',    '-',    '=',    K_BACKSPACE, 9, // 0 
  111.     'q',    'w',    'e',    'r',    't',    'y',    'u',    'i', 
  112.     'o',    'p',    '[',    ']',    13 ,    K_CTRL,'a',  's',      // 1 
  113.     'd',    'f',    'g',    'h',    'j',    'k',    'l',    ';', 
  114.     '\'' ,    '`',    K_SHIFT,'\\',  'z',    'x',    'c',    'v',      // 2 
  115.     'b',    'n',    'm',    ',',    '.',    '/',    K_SHIFT,'*', 
  116.     K_ALT,' ',   0  ,    K_F1, K_F2, K_F3, K_F4, K_F5,   // 3 
  117.     K_F6, K_F7, K_F8, K_F9, K_F10,  K_PAUSE,    0  , K_HOME, 
  118.     K_UPARROW,K_PGUP,K_KP_MINUS,K_LEFTARROW,K_KP_5,K_RIGHTARROW, K_KP_PLUS,K_END, //4 
  119.     K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0,             0,              K_F11, 
  120.     K_F12,0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,        // 5
  121.     0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0, 
  122.     0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,        // 6 
  123.     0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0, 
  124.     0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0         // 7 
  125. }; 
  126.  
  127. /*
  128. =======
  129. MapKey
  130.  
  131. Map from windows to quake keynums
  132. =======
  133. */
  134. int MapKey (int key)
  135. {
  136.     int result;
  137.     int modified = ( key >> 16 ) & 255;
  138.     qboolean is_extended = false;
  139.  
  140.     if ( modified > 127)
  141.         return 0;
  142.  
  143.     if ( key & ( 1 << 24 ) )
  144.         is_extended = true;
  145.  
  146.     result = scantokey[modified];
  147.  
  148.     if ( !is_extended )
  149.     {
  150.         switch ( result )
  151.         {
  152.         case K_HOME:
  153.             return K_KP_HOME;
  154.         case K_UPARROW:
  155.             return K_KP_UPARROW;
  156.         case K_PGUP:
  157.             return K_KP_PGUP;
  158.         case K_LEFTARROW:
  159.             return K_KP_LEFTARROW;
  160.         case K_RIGHTARROW:
  161.             return K_KP_RIGHTARROW;
  162.         case K_END:
  163.             return K_KP_END;
  164.         case K_DOWNARROW:
  165.             return K_KP_DOWNARROW;
  166.         case K_PGDN:
  167.             return K_KP_PGDN;
  168.         case K_INS:
  169.             return K_KP_INS;
  170.         case K_DEL:
  171.             return K_KP_DEL;
  172.         default:
  173.             return result;
  174.         }
  175.     }
  176.     else
  177.     {
  178.         switch ( result )
  179.         {
  180.         case 0x0D:
  181.             return K_KP_ENTER;
  182.         case 0x2F:
  183.             return K_KP_SLASH;
  184.         case 0xAF:
  185.             return K_KP_PLUS;
  186.         }
  187.         return result;
  188.     }
  189. }
  190.  
  191. void AppActivate(BOOL fActive, BOOL minimize)
  192. {
  193.     Minimized = minimize;
  194.  
  195.     Key_ClearStates();
  196.  
  197.     // we don't want to act like we're active if we're minimized
  198.     if (fActive && !Minimized)
  199.         ActiveApp = true;
  200.     else
  201.         ActiveApp = false;
  202.  
  203.     // minimize/restore mouse-capture on demand
  204.     if (!ActiveApp)
  205.     {
  206.         IN_Activate (false);
  207.         CDAudio_Activate (false);
  208.         S_Activate (false);
  209.  
  210.         if ( win_noalttab->value )
  211.         {
  212.             WIN_EnableAltTab();
  213.         }
  214.     }
  215.     else
  216.     {
  217.         IN_Activate (true);
  218.         CDAudio_Activate (true);
  219.         S_Activate (true);
  220.         if ( win_noalttab->value )
  221.         {
  222.             WIN_DisableAltTab();
  223.         }
  224.     }
  225. }
  226.  
  227. /*
  228. ====================
  229. MainWndProc
  230.  
  231. main window procedure
  232. ====================
  233. */
  234. LONG WINAPI MainWndProc (
  235.     HWND    hWnd,
  236.     UINT    uMsg,
  237.     WPARAM  wParam,
  238.     LPARAM  lParam)
  239. {
  240.     LONG            lRet = 0;
  241.  
  242.     if ( uMsg == MSH_MOUSEWHEEL )
  243.     {
  244.         if ( ( ( int ) wParam ) > 0 )
  245.         {
  246.             Key_Event( K_MWHEELUP, true, sys_msg_time );
  247.             Key_Event( K_MWHEELUP, false, sys_msg_time );
  248.         }
  249.         else
  250.         {
  251.             Key_Event( K_MWHEELDOWN, true, sys_msg_time );
  252.             Key_Event( K_MWHEELDOWN, false, sys_msg_time );
  253.         }
  254.         return DefWindowProc (hWnd, uMsg, wParam, lParam);
  255.     }
  256.  
  257.     switch (uMsg)
  258.     {
  259.     case WM_MOUSEWHEEL:
  260.         /*
  261.         ** this chunk of code theoretically only works under NT4 and Win98
  262.         ** since this message doesn't exist under Win95
  263.         */
  264.         if ( ( short ) HIWORD( wParam ) > 0 )
  265.         {
  266.             Key_Event( K_MWHEELUP, true, sys_msg_time );
  267.             Key_Event( K_MWHEELUP, false, sys_msg_time );
  268.         }
  269.         else
  270.         {
  271.             Key_Event( K_MWHEELDOWN, true, sys_msg_time );
  272.             Key_Event( K_MWHEELDOWN, false, sys_msg_time );
  273.         }
  274.         break;
  275.  
  276.     case WM_HOTKEY:
  277.         return 0;
  278.  
  279.     case WM_CREATE:
  280.         cl_hwnd = hWnd;
  281.  
  282.         MSH_MOUSEWHEEL = RegisterWindowMessage("MSWHEEL_ROLLMSG"); 
  283.         return DefWindowProc (hWnd, uMsg, wParam, lParam);
  284.  
  285.     case WM_PAINT:
  286.         SCR_DirtyScreen ();    // force entire screen to update next frame
  287.         return DefWindowProc (hWnd, uMsg, wParam, lParam);
  288.  
  289.     case WM_DESTROY:
  290.         // let sound and input know about this?
  291.         cl_hwnd = NULL;
  292.         return DefWindowProc (hWnd, uMsg, wParam, lParam);
  293.  
  294.     case WM_ACTIVATE:
  295.         {
  296.             int    fActive, fMinimized;
  297.  
  298.             // KJB: Watch this for problems in fullscreen modes with Alt-tabbing.
  299.             fActive = LOWORD(wParam);
  300.             fMinimized = (BOOL) HIWORD(wParam);
  301.  
  302.             AppActivate( fActive != WA_INACTIVE, fMinimized);
  303.  
  304.             if ( reflib_active )
  305.                 R_AppActivate( !( fActive == WA_INACTIVE ) );
  306.         }
  307.         return DefWindowProc (hWnd, uMsg, wParam, lParam);
  308.  
  309.     case WM_MOVE:
  310.         {
  311.             int        xPos, yPos;
  312.             RECT r;
  313.             int        style;
  314.  
  315.             if (!vid_fullscreen->value)
  316.             {
  317.                 xPos = (short) LOWORD(lParam);    // horizontal position 
  318.                 yPos = (short) HIWORD(lParam);    // vertical position 
  319.  
  320.                 r.left   = 0;
  321.                 r.top    = 0;
  322.                 r.right  = 1;
  323.                 r.bottom = 1;
  324.  
  325.                 style = GetWindowLong( hWnd, GWL_STYLE );
  326.                 AdjustWindowRect( &r, style, FALSE );
  327.  
  328.                 Cvar_SetValue( "vid_xpos", xPos + r.left);
  329.                 Cvar_SetValue( "vid_ypos", yPos + r.top);
  330.                 vid_xpos->modified = false;
  331.                 vid_ypos->modified = false;
  332.                 if (ActiveApp)
  333.                     IN_Activate (true);
  334.             }
  335.         }
  336.         return DefWindowProc (hWnd, uMsg, wParam, lParam);
  337.  
  338. // this is complicated because Win32 seems to pack multiple mouse events into
  339. // one update sometimes, so we always check all states and look for events
  340.     case WM_LBUTTONDOWN:
  341.     case WM_LBUTTONUP:
  342.     case WM_RBUTTONDOWN:
  343.     case WM_RBUTTONUP:
  344.     case WM_MBUTTONDOWN:
  345.     case WM_MBUTTONUP:
  346.     case WM_MOUSEMOVE:
  347.         {
  348.             int    temp;
  349.  
  350.             temp = 0;
  351.  
  352.             if (wParam & MK_LBUTTON)
  353.                 temp |= 1;
  354.  
  355.             if (wParam & MK_RBUTTON)
  356.                 temp |= 2;
  357.  
  358.             if (wParam & MK_MBUTTON)
  359.                 temp |= 4;
  360.  
  361.             IN_MouseEvent (temp);
  362.         }
  363.         break;
  364.  
  365.     case WM_SYSCOMMAND:
  366.         if ( wParam == SC_SCREENSAVE )
  367.             return 0;
  368.         return DefWindowProc (hWnd, uMsg, wParam, lParam);
  369.     case WM_SYSKEYDOWN:
  370.         if ( wParam == 13 )
  371.         {
  372.             if ( vid_fullscreen )
  373.             {
  374.                 Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value );
  375.             }
  376.             return 0;
  377.         }
  378.         // fall through
  379.     case WM_KEYDOWN:
  380.         Key_Event( MapKey( lParam ), true, sys_msg_time);
  381.         break;
  382.  
  383.     case WM_SYSKEYUP:
  384.     case WM_KEYUP:
  385.         Key_Event( MapKey( lParam ), false, sys_msg_time);
  386.         break;
  387.  
  388.     case MM_MCINOTIFY:
  389.         {
  390.             LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  391.             lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam);
  392.         }
  393.         break;
  394.  
  395.     default:    // pass all unhandled messages to DefWindowProc
  396.         return DefWindowProc (hWnd, uMsg, wParam, lParam);
  397.     }
  398.  
  399.     /* return 0 if handled message, 1 if not */
  400.     return DefWindowProc( hWnd, uMsg, wParam, lParam );
  401. }
  402.  
  403. /*
  404. ============
  405. VID_Restart_f
  406.  
  407. Console command to re-start the video mode and refresh DLL. We do this
  408. simply by setting the modified flag for the vid_ref variable, which will
  409. cause the entire video mode and refresh DLL to be reset on the next frame.
  410. ============
  411. */
  412. void VID_Restart_f (void)
  413. {
  414.     vid_ref->modified = true;
  415. }
  416.  
  417. void VID_Front_f( void )
  418. {
  419.     SetWindowLong( cl_hwnd, GWL_EXSTYLE, WS_EX_TOPMOST );
  420.     SetForegroundWindow( cl_hwnd );
  421. }
  422.  
  423. /*
  424. ** VID_GetModeInfo
  425. */
  426. typedef struct vidmode_s
  427. {
  428.     const char *description;
  429.     int         width, height;
  430.     int         mode;
  431. } vidmode_t;
  432.  
  433. //Gonna get rid of the lower resolution - so that the HUD doesn't get knocked off the screen
  434. //besides, who the hell wants to play at anything less than 640x480
  435. vidmode_t vid_modes[] =
  436. {
  437.     { "Mode 0: 640x480",   640, 480,   0 },
  438.     { "Mode 1: 640x480",   640, 480,   1 },
  439.     { "Mode 2: 640x480",   640, 480,   2 },
  440.     { "Mode 3: 640x480",   640, 480,   3 },
  441.     { "Mode 4: 800x600",   800, 600,   4 },
  442.     { "Mode 5: 960x720",   960, 720,   5 },
  443.     { "Mode 6: 1024x768",  1024, 768,  6 },
  444.     { "Mode 7: 1152x864",  1152, 864,  7 },
  445.     { "Mode 8: 1280x960",  1280, 960, 8 },
  446.     { "Mode 9: 1600x1200", 1600, 1200, 9 },
  447.     { "Mode 10: 2048x1536", 2048, 1536, 10 }
  448. };
  449.  
  450. qboolean VID_GetModeInfo( int *width, int *height, int mode )
  451. {
  452.     if ( mode < 0 || mode >= VID_NUM_MODES )
  453.         return false;
  454.  
  455.     *width  = vid_modes[mode].width;
  456.     *height = vid_modes[mode].height;
  457.  
  458.     return true;
  459. }
  460.  
  461. /*
  462. ** VID_UpdateWindowPosAndSize
  463. */
  464. void VID_UpdateWindowPosAndSize( int x, int y )
  465. {
  466.     RECT r;
  467.     int        style;
  468.     int        w, h;
  469.  
  470.     r.left   = 0;
  471.     r.top    = 0;
  472.     r.right  = viddef.width;
  473.     r.bottom = viddef.height;
  474.  
  475.     style = GetWindowLong( cl_hwnd, GWL_STYLE );
  476.     AdjustWindowRect( &r, style, FALSE );
  477.  
  478.     w = r.right - r.left;
  479.     h = r.bottom - r.top;
  480.  
  481.     MoveWindow( cl_hwnd, vid_xpos->value, vid_ypos->value, w, h, TRUE );
  482. }
  483.  
  484. /*
  485. ** VID_NewWindow
  486. */
  487. void VID_NewWindow ( int width, int height)
  488. {
  489.     viddef.width  = width;
  490.     viddef.height = height;
  491.  
  492.     cl.force_refdef = true;        // can't use a paused refdef
  493. }
  494.  
  495. void VID_FreeReflib (void)
  496. {
  497.     reflib_active  = false;
  498. }
  499.  
  500. /*
  501. ==============
  502. VID_LoadRefresh
  503. ==============
  504. */
  505. qboolean VID_LoadRefresh(void)
  506. {
  507.     if ( reflib_active )
  508.     {
  509.         R_Shutdown();
  510.         VID_FreeReflib ();
  511.     }
  512.  
  513.     if ( R_Init( global_hInstance, MainWndProc ) == -1 )
  514.     {
  515.         R_Shutdown();
  516.         VID_FreeReflib ();
  517.         return false;
  518.     }
  519.  
  520.     Com_Printf( "------------------------------------\n");
  521.     reflib_active = true;
  522.  
  523.     return true;
  524. }
  525.  
  526. /*
  527. ============
  528. VID_CheckChanges
  529.  
  530. This function gets called once just before drawing each frame, and it's sole purpose in life
  531. is to check to see if any of the video mode parameters have changed, and if they have to 
  532. update the rendering DLL and/or video mode to match.
  533. ============
  534. */
  535. void VID_CheckChanges (void)
  536. {
  537.     if ( win_noalttab->modified )
  538.     {
  539.         if ( win_noalttab->value )
  540.         {
  541.             WIN_DisableAltTab();
  542.         }
  543.         else
  544.         {
  545.             WIN_EnableAltTab();
  546.         }
  547.         win_noalttab->modified = false;
  548.     }
  549.  
  550.     if ( vid_ref->modified )
  551.     {
  552.         cl.force_refdef = true;        // can't use a paused refdef
  553.         S_StopAllSounds();
  554.     }
  555.     while (vid_ref->modified)
  556.     {
  557.         /*
  558.         ** refresh has changed
  559.         */
  560.         vid_ref->modified = false;
  561.         vid_fullscreen->modified = true;
  562.         cl.refresh_prepped = false;
  563.         cls.disable_screen = true;
  564.  
  565.         if ( !VID_LoadRefresh() )
  566.         {
  567.             /*
  568.             ** drop the console if we fail to load a refresh
  569.             */
  570.             if ( cls.key_dest != key_console )
  571.             {
  572.                 Con_ToggleConsole_f();
  573.             }
  574.         }
  575.         cls.disable_screen = false;
  576.     }
  577.  
  578.     /*
  579.     ** update our window position
  580.     */
  581.     if ( vid_xpos->modified || vid_ypos->modified )
  582.     {
  583.         if (!vid_fullscreen->value)
  584.             VID_UpdateWindowPosAndSize( vid_xpos->value, vid_ypos->value );
  585.  
  586.         vid_xpos->modified = false;
  587.         vid_ypos->modified = false;
  588.     }
  589. }
  590.  
  591. /*
  592. ============
  593. VID_Init
  594. ============
  595. */
  596. void VID_Init (void)
  597. {
  598.     /* Create the video variables so we know how to start the graphics drivers */
  599.     vid_ref = Cvar_Get ("vid_ref", "soft", CVAR_ARCHIVE);
  600.     vid_xpos = Cvar_Get ("vid_xpos", "3", CVAR_ARCHIVE);
  601.     vid_ypos = Cvar_Get ("vid_ypos", "22", CVAR_ARCHIVE);
  602.     vid_fullscreen = Cvar_Get ("vid_fullscreen", "0", CVAR_ARCHIVE);
  603.     vid_gamma = Cvar_Get( "vid_gamma", "1", CVAR_ARCHIVE );
  604.     win_noalttab = Cvar_Get( "win_noalttab", "0", CVAR_ARCHIVE );
  605.  
  606.     /* Add some console commands that we want to handle */
  607.     Cmd_AddCommand ("vid_restart", VID_Restart_f);
  608.     Cmd_AddCommand ("vid_front", VID_Front_f);
  609.  
  610.     /*
  611.     ** this is a gross hack but necessary to clamp the mode for 3Dfx
  612.     */
  613. #if 0
  614.     {
  615.         cvar_t *gl_driver = Cvar_Get( "gl_driver", "opengl32", 0 );
  616.         cvar_t *gl_mode = Cvar_Get( "gl_mode", "3", 0 );
  617.  
  618.         if ( stricmp( gl_driver->string, "3dfxgl" ) == 0 )
  619.         {
  620.             Cvar_SetValue( "gl_mode", 3 );
  621.             viddef.width  = 640;
  622.             viddef.height = 480;
  623.         }
  624.     }
  625. #endif
  626.  
  627.     /* Disable the 3Dfx splash screen */
  628.     putenv("FX_GLIDE_NO_SPLASH=0");
  629.         
  630.     /* Start the graphics mode and load refresh DLL */
  631.     VID_CheckChanges();
  632. }
  633.  
  634. /*
  635. ============
  636. VID_Shutdown
  637. ============
  638. */
  639. void VID_Shutdown (void)
  640. {
  641.     if ( reflib_active )
  642.     {
  643.         R_Shutdown ();
  644.         VID_FreeReflib ();
  645.     }
  646. }
  647.  
  648.  
  649.